import axios from 'axios';
import { getToken } from './auth';
import qs from 'qs';
import { setSession, getSession } from './cache';
import { notification, Modal } from 'antd';
const { confirm } = Modal;
import { history, getLocale } from 'umi';
import { ExclamationCircleOutlined as Outlined } from '@ant-design/icons';

const xsrfHeadName = 'Authorization';
const timeout = 10000;
// const BASE_URL = process.env.VUE_APP_API_BASE_URL;
const BASE_URL = '/api';

// 认证类型
const AUTH_TYPE = {
  BEARER: 'Bearer ',
  BASIC: 'basic',
  AUTH1: 'auth1',
  AUTH2: 'auth2',
};

// http method
const METHOD = {
  GET: 'get',
  POST: 'post',
  DELETE: 'delete',
  PUT: 'put',
};

const errorCode = {
  401: '认证失败，无法访问系统资源',
  403: '当前操作没有权限',
  404: '访问资源不存在',
  default: '系统出错了....',
};

// 创建axios实例
const service = axios.create({
  baseURL: BASE_URL,
  // 超时
  timeout: timeout,
});

type RestResponse = {
  msg: string,
  data: object,
  isSuccess: boolean,
  code: number
}
//get请求拼接URL
const getParamsUrl = (url: string, params: object): string => {
  return url + '?' + qs.stringify(params);
};


//设置json参数的方式请求
axios.defaults.headers['Content-Type'] = 'application/json;charset=UTF-8';

// 不允许携带cookie
axios.defaults.withCredentials = false;

// 请求拦截器
service.interceptors.request.use(
  (config: any) => {
    // 设置国际化语言
    config.headers.lang = getLocale();
    //是否需要携带token
    const hasToken = (config.headers || {}).hasToken === false;
    //是否需要防止重复提交
    const hasRepeatSubmit = (config.headers || {}).hasRepeatSubmit === undefined ? true : false;

    //如果cookie存在token 并且需要携带token 则将token放入请求头中
    if (getToken() && !hasToken) {
      config.headers[xsrfHeadName] = AUTH_TYPE.BEARER + getToken();
    }
    // GET 请求参数转换
    if (config.method === METHOD.GET && config.params) {
      const url = getParamsUrl(config.url, config.params );
      config.params = {};
      config.url = url;
    }

    // 重复提交
    if (!hasRepeatSubmit && (config.method === METHOD.POST || config.method === METHOD.PUT)) {
      const requestObj = {
        url: config.url,
        data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
        time: new Date().getTime(),
      };
      const repeatSubmitOb = getSession('repeatSubmit');
      if (repeatSubmitOb === undefined || repeatSubmitOb === null || repeatSubmitOb === '') {
        setSession('repeatSubmit', requestObj);
      } else {
        const submitData = repeatSubmitOb as Utils.IRepeat;
        const s_url = submitData.url; // 请求地址
        const s_data = submitData.data; // 请求数据
        const s_time = submitData.time; // 请求时间
        const interval = 1000; // 间隔时间(ms)，小于此时间视为重复提交
        if (
          s_data === requestObj.data &&
          requestObj.time - s_time < interval &&
          s_url === requestObj.url
        ) {
          const message = '数据正在处理，请勿重复提交';
          console.warn(`[${s_url}]: ` + message);
          return Promise.reject(new Error(message));
        } else {
          setSession('repeatSubmit',requestObj)
        }
      }
    }
    return config;
  },
  (error) => {
    console.log(error);
    Promise.reject(error);
  },
);

// 响应拦截器
service.interceptors.response.use(
  (res) => {
    const data: RestResponse  = res.data;
    // 未设置状态码则默认成功状态
    const code = data.code || 200;
    // 获取错误信息
    // eslint-disable-next-line @typescript-eslint/dot-notation
    const msg = errorCode[code] || data.msg || errorCode['default'];
    // 二进制数据则直接返回
    if (code === 401) {
      // 重定向登录页面
      confirm({
        icon: Outlined,
        title: '你的账号已过期，请重新登录',
        onOk() {
          history.push('/user/login');
        },
      });
      return Promise.reject(msg);
    }
    if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
      return res.data;
    }
    switch (code) {
      case 500:
        notification.error({
          message: msg,
        });
        return Promise.reject(msg);
      case 200:
        return Promise.resolve(res.data);
      default:
        notification.error({
          message: msg,
        });
    }
  },
  (error) => {
    console.log('err' + error);
    let { message } = error;
    if (message == 'Network Error') {
      message = '后端接口连接异常，请检查网络或服务';
    } else if (message.includes('timeout')) {
      message = '系统接口请求超时';
    } else if (message.includes('Request failed with status code')) {
      message = '系统接口' + message.substr(message.length - 3) + '异常';
    }
    // Notification["error"]({
    //     message: message
    // })
    notification.error({
      message: message,
    });
    return Promise.reject(error);
  },
);

export default service;

